package com.sumainfor.pc.epc.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.sumainfor.common.entity.MoSupplierObject;
import com.sumainfor.common.exception.TCException;
import com.sumainfor.common.util.*;
import com.sumainfor.common.utlis.ComUtils;
import com.sumainfor.common.utlis.MoSupplierObjectUtil;
import com.sumainfor.common.utlis.ParamsCommon;
import com.sumainfor.pc.epc.dao.BuyerManageMapper;
import com.sumainfor.pc.epc.dao.HousingConfigChangeMapper;
import com.sumainfor.pc.epc.dao.StockManageMapper;
import com.sumainfor.pc.epc.dao.SupplierManageMapper;
import com.sumainfor.pc.epc.feign.GetUserInfoFeign;
import com.sumainfor.pc.epc.feign.Housingauditfeign;
import com.sumainfor.pc.epc.service.HousingConfigChangeService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author PuaChen
 * @Create 2018-11-26 17:46
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Log4j2
public class HousingConfigChangeServiceImpl implements HousingConfigChangeService {

    @Autowired
    private SupplierManageMapper supplierManageMapper;

    @Autowired
    private StockManageMapper stockManageMapper;

    @Autowired
    private GetUserInfoFeign userInfoFeign;

    @Autowired
    private Housingauditfeign housingauditfeign;

    @Autowired
    private BuyerManageMapper buyerManageMapper;

    @Autowired
    private HousingConfigChangeMapper housingConfigChangeMapper;

    @Autowired
    private ComUtils comUtils;

    /**
     * 查询列表
     *
     * @param page
     * @param params
     * @return
     */
    @Override
    public JsonResult selectConfigList(Page page, Map<String, Object> params) {
        //1待处理 2.验收中 3通过
        Integer state = MapUtils.getInteger(params, "state");
        IPage<Map<String, Object>> resPage = housingConfigChangeMapper.selectConfigList(page, state);

        if (resPage.getRecords().isEmpty()) {
            return JsonResult.success(resPage);
        }

        //处理加入数据
        List<String> houIds = Lists.newArrayList();
        Set<String> userIds = Sets.newHashSet();
        for (Map<String, Object> map : resPage.getRecords()) {
            houIds.add(MapUtils.getString(map, "HouId"));
            userIds.add(MapUtils.getString(map, "LaunchUserId"));
        }

        JsonResult<List<Map<String, Object>>> houRes = housingauditfeign.getProjectNameAndHousingConf(houIds);
        JsonResult<List<Map<String, Object>>> userRes = userInfoFeign.getUserInfo(userIds);
        if (!userRes.isSuccess()) {
            return JsonResult.error("查询用户信息失败");
        }
        if (!houRes.isSuccess()) {
            return JsonResult.error("查询房源信息失败");
        }

        for (Map<String, Object> map : resPage.getRecords()) {
            //查询移除物品数和新增物品数

            List<Map<String, Object>> altInfoList = housingConfigChangeMapper.selectConfigInfoListByConfId(MapUtils.getString(map, "altId"));
            if (CollectionUtils.isEmpty(altInfoList)) {
                return JsonResult.error("找不到配置物品");
            }

            //获取新增和移除物品数
            int newCount = 0;
            int removeCount = 0;
            for (Map<String, Object> info : altInfoList) {
                int old = MapUtils.getIntValue(info, "ComNumber");
                int change = MapUtils.getIntValue(info, "RealComNumber");
                if (old == change) {
                    continue;
                }
                if (old < change) {
                    //新增
                    newCount++;
                } else {
                    //移除
                    removeCount++;
                }
            }
            map.put("newCount", newCount);
            map.put("removeCount", removeCount);


            for (Map<String, Object> hData : houRes.getResult()) {
                if (MapUtils.getString(map, "HouId").equals(MapUtils.getString(hData, "HouId"))) {
                    map.put("ComName", hData.get("ComName"));
                    String local = MapUtils.getString(hData, "Building") + "栋" + MapUtils.getString(hData, "Floor") + "楼" + MapUtils.getString(hData, "Room") + "室";
                    map.put("local", local);
                }
            }
            for (Map<String, Object> uData : userRes.getResult()) {
                if (Objects.equals(MapUtils.getString(map, "LaunchUserId"), MapUtils.getString(uData, "user_id"))) {
                    map.put("UserName", uData.get("username"));
                    map.put("mobile", uData.get("mobile"));
                    map.put("deptName", uData.get("deptName"));
                    //是否是管家创建
                    map.put("isButler", MapUtils.getString(uData, "deptName", "").contains("管家") ? true : false);
                }
            }
        }
        return JsonResult.success(resPage);
    }

    /**
     * 获得 房源配置变更详情数据
     *
     * @param confId
     * @return
     */
    @Override
    public JsonResult getConfigInfo(String confId) {
        List<Map<String, Object>> dataList = housingConfigChangeMapper.selectConfigInfoListByConfId(confId);
        List<CustomMap> data = Lists.newArrayList();
        List<String> groupHouName = housingConfigChangeMapper.getConfigInfoHouNameCountById(confId);
        for (String s : groupHouName) {
            data.add(CustomMap.create("name", s).put("list", Lists.newArrayList()));
        }

        for (Map<String, Object> map : dataList) {
            map.put("ComTypeId", MapUtils.getString(map, "ComType"));
            map.put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(map, "ComType")));

            int old = MapUtils.getIntValue(map, "ComNumber");
            int change = MapUtils.getIntValue(map, "RealComNumber");
            map.remove("ComNumber");
            if (old < change) {
                //新增 出库
                map.put("Action", 1);
            } else {
                //移除 入库
                map.put("Action", 0);
            }
            map.put("RealComNumber", Math.abs(old - change));
            //分组
            for (CustomMap datum : data) {
                if (datum.getToString("name").equals(MapUtils.getString(map, "HouConName"))) {
                    ((List<Map<String, Object>>) datum.get("list")).add(map);
                }
            }
        }
        return JsonResult.success(data);
    }

    /**
     * 根据商品的名称 和 规格的名称 + 商品的类型int 查询关联的品牌商品列表
     *
     * @param params
     * @return
     */
    @Override
    public JsonResult getSpinnerForBrandList(Map<String, String> params) {
        String shopName = params.get("ComName");
        String speName = params.get("ComSpeName");
        String comType = params.get("ComType");
        return JsonResult.success(housingConfigChangeMapper.getSpinnerForBrandList(shopName, speName, comType));
    }

    /**
     * 根据 商品的ID 和规格的名称去查询型号表的所有的信息
     *
     * @param shopId
     * @param speName
     * @return
     */
    @Override
    public JsonResult getSpinnerForMoList(String shopId, String speName) {
        return JsonResult.success(housingConfigChangeMapper.getSpinnerForMoList(shopId, speName));
    }

    /**
     * 通过型号的编号 查出来所有的供应商
     *
     * @param moId
     * @return
     */
    @Override
    public JsonResult getSupplierAndPrice(String moId) {
        Map<String, Object> moData = stockManageMapper.getShopMoForInfos(moId);
        if (MapUtils.isEmpty(moData)) {
            return JsonResult.error("查询这个型号失败");
        }
        List<MoSupplierObject> list = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(moData, "supplier"));
        return JsonResult.success(list.stream().map(item -> {
            Map<String, Object> supplierOne = supplierManageMapper.getSupplierOne(item.getSupplierId());
            return ObjectUtil.convertObjectToMap(item).put("supName", supplierOne.get("UnitName"));
        }).collect(Collectors.toList()));
    }


    /**
     * 出库的操作
     *
     * @param params
     * @return
     */
    @Override
    public JsonResult outPutStock(Map<String, Object> params) {
        //型号的编号
        String moId = MapUtils.getString(params, "moId");
        //出库的数量
        int count = MapUtils.getIntValue(params, "count");
        //供应商的ID
        String supId = MapUtils.getString(params, "supId");
        //详表的ID
        Integer id = MapUtils.getInteger(params, "id");

        //1.去查询详表记录
        Map<String, Object> configInfo = housingConfigChangeMapper.getConfigInfoById(id);

        if (MapUtils.isEmpty(configInfo)) {
            return JsonResult.error("没有查询到这条记录");
        }
        if (Objects.equals(MapUtils.getInteger(configInfo, "DepState"), 2)) {
            return JsonResult.error("这个商品已经配置了");
        }

        int old = MapUtils.getIntValue(configInfo, "ComNumber");
        int change = MapUtils.getIntValue(configInfo, "RealComNumber");

        if (old > change) {
            return JsonResult.error("这个商品不是出库的操作");
        }


        //判断型号不为空的时候
        if (FieldCheckUtil.isMapFieldNotNull(configInfo, "ComSpeMoId")) {
            if (!Objects.equals(MapUtils.getString(configInfo, "ComSpeMoId"), moId)) {
                return JsonResult.error("两次入库的商品不是同一个型号,不能进行出库的操作");
            }
        }

        //已出库的数量
        int doneCount = MapUtils.getIntValue(configInfo, "DoneCount");
        int comNumber = MapUtils.getIntValue(configInfo, "ComNumber");
        int allCount = Math.abs(comNumber - MapUtils.getIntValue(configInfo, "RealComNumber"));
        if (doneCount >= allCount) {
            return JsonResult.error("此商品已经完成出库的操作");
        }
        if ((doneCount + count) > allCount) {
            return JsonResult.error("出库的数量不能大于需要出库的总数量");
        }
        //DepState 配置状态   1.配置中   2.已配置
        //采购录入型号的时候去修改这个状态
        int state = 1;
        if ((doneCount + count) == allCount) {
            state = 2;
        }
        //查询型号的相关信息
        Map<String, Object> moInfo = stockManageMapper.getShopMoForInfos(moId);
        if (MapUtils.isEmpty(moInfo)) {
            return JsonResult.error("没有这个商品的信息");
        }
        //构建变更表 更新的数据
        int row = housingConfigChangeMapper.updateConfigInfoById(ParamsCommon.commonUpdateParms(CustomMap.converToCustomMap(configInfo)
                        .put("DoneCount", count + doneCount)
                        .put("DepState", state)
                        .put("ComSpeId", moInfo.get("ComSpeId"))
                        .put("ComSpeMoId", moId)
                        .put("SupId", supId)
                        .put("ComSpeMoName", moInfo.get("ComSpeMoName"))
                , getClass()));
        if (row <= 0) {
            return JsonResult.error("修改失败");
        }

        //修改商品的库存数据
        List<MoSupplierObject> moSupList = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(moInfo, "supplier"));
        MoSupplierObject supObj = MoSupplierObjectUtil.selectSupplierById(moSupList, supId);
        if (supObj == null) {
            throw new TCException("没有查到这个供应商绑定了这个商品");
        }
        //元库存数
        int oldCount = supObj.getStoreCount();
        supObj.subStoreCount(count);
        moInfo.put("supplier", MoSupplierObjectUtil.toJson(moSupList));
        moInfo.put("Stock", MapUtils.getIntValue(moInfo, "Stock") - count);
        row = buyerManageMapper.updateShopForMo(ParamsCommon.commonUpdateParms(moInfo, getClass()));
        if (row <= 0) {
            return JsonResult.error("减少商品库存失败");
        }
        //添加出库的记录
        //1.构建数据参数
        CustomMap logOutMap = CustomMap.create("ComOutId", UUIDUtils.generatePrefixUuid("OutLog"))
                .put("ComOutType", 2)
                .put("SysUserId", MapUtils.getString(configInfo, "insby"))
                .put("ComSpeMoId", moId)
                .put("SupId", supId)
                //原来库存数量
                .put("RawInventory ", oldCount)
                //出库存数量
                .put("ComInventory ", count)
                //现在库存数量
                .put("CasInventory ", supObj.getStoreCount());
        ParamsCommon.commonInsertParms(logOutMap);
        //2. 数据库插入
        row = stockManageMapper.insertStockMainWriteOutLog(ParamsCommon.commonInsertParms(logOutMap, getClass()));
        if (row <= 0) {
            throw new TCException("创建出库记录失败");
        }
        return JsonResult.success();
    }

    /**
     * 入库的操作
     * removeCount
     *
     * @param params
     * @return
     */
    @Override
    public JsonResult inPutStock(Map<String, Object> params) {
        Integer id = MapUtils.getInteger(params, "id");
        //移除的数量
        int removeCount = MapUtils.getIntValue(params, "removeCount", 0);
        //入库数量
        int inCount = MapUtils.getIntValue(params, "inCount", 0);

        //1.去查询详表记录
        Map<String, Object> configInfo = housingConfigChangeMapper.getConfigInfoById(id);

        if (MapUtils.isEmpty(configInfo)) {
            return JsonResult.error("没有查询到这条记录");
        }
        if (Objects.equals(MapUtils.getInteger(configInfo, "DepState"), 2)) {
            return JsonResult.error("这个商品已经配置了");
        }

        int old = MapUtils.getIntValue(configInfo, "ComNumber");
        int change = MapUtils.getIntValue(configInfo, "RealComNumber");

        if (old < change) {
            return JsonResult.error("这个商品不是入库的操作");
        }


        //已入库的数量
        int comNumber = MapUtils.getIntValue(configInfo, "ComNumber");
        int allCount = Math.abs(comNumber - MapUtils.getIntValue(configInfo, "RealComNumber"));
        int dInCount = MapUtils.getIntValue(configInfo, "DoneCount");
        int dRemoveCount = MapUtils.getIntValue(configInfo, "RemoveCount");
        if ((dInCount + dRemoveCount) >= allCount) {
            return JsonResult.error("此商品已经完成入库的操作");
        }
        if ((dInCount + dRemoveCount + inCount + removeCount) > allCount) {
            return JsonResult.error("入库的数量不能大于需要入库的总数量");
        }


        //DepState 配置状态   1.配置中   2.已配置
        //采购录入型号的时候去修改这个状态
        int state = 1;
        if ((dInCount + dRemoveCount + inCount + removeCount) == allCount) {
            state = 2;
        }
        //构建变更表 更新的数据
        configInfo.put("DoneCount", inCount + dInCount);
        configInfo.put("RemoveCount", dRemoveCount + removeCount);
        configInfo.put("DepState", state);
        int row = housingConfigChangeMapper.updateConfigInfoById(ParamsCommon.commonUpdateParms(configInfo, getClass()));
        if (row <= 0) {
            throw new TCException("修改失败");
        }

        if (inCount != 0) {
            //查询型号的相关信息
            Map<String, Object> moInfo = stockManageMapper.getShopMoForInfos(MapUtils.getString(configInfo, "ComSpeMoId"));
            if (MapUtils.isEmpty(moInfo)) {
                return JsonResult.error("没有这个商品的信息");
            }

            //修改商品的库存数据
            List<MoSupplierObject> moSupList = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(moInfo, "supplier"));
            MoSupplierObject supObj = MoSupplierObjectUtil.selectSupplierById(moSupList, MapUtils.getString(configInfo, "SupId"));
            if (supObj == null) {
                throw new TCException("没有查到这个供应商绑定了这个商品");
            }
            //元库存数
            int oldCount = supObj.getStoreCount();
            supObj.addStoreCount(inCount);
            moInfo.put("supplier", MoSupplierObjectUtil.toJson(moSupList));
            moInfo.put("Stock", MapUtils.getIntValue(moInfo, "Stock") + inCount);
            row = buyerManageMapper.updateShopForMo(ParamsCommon.commonUpdateParms(moInfo, getClass()));
            if (row <= 0) {
                return JsonResult.error("入库失败");
            }
            //进行入库的记录的操作
            String uuid = UUIDUtils.generatePrefixUuid("StockInLog");
            CustomMap logData = CustomMap.create("ComInId", uuid)
                    .put("ComSpeMoId", MapUtils.getString(moInfo, "ComSpeMoId"))
                    .put("SupId", supObj.getSupplierId())
                    .put("RawInventory", oldCount)
                    .put("ComInventory", inCount)
                    .put("CasInventory", supObj.getStoreCount());
            ParamsCommon.commonInsertParms(logData, getClass());
            row = buyerManageMapper.insertStoreInPutLog(logData);
            if (row <= 0) {
                throw new TCException("商品入库添加日志出现异常,操作失败");
            }
        }

        return JsonResult.success();
    }

    /**
     * 获得某一条数据的详情
     *
     * @param params
     * @return
     */
    @Override
    public JsonResult getItemInfo(Map<String, Object> params) {
        Integer id = MapUtils.getInteger(params, "id");
        Map<String, Object> conInfo = housingConfigChangeMapper.getConfigInfoById(id);
        if (MapUtils.isEmpty(conInfo)) {
            return JsonResult.error("没有这条数据");
        }
        if (conInfo.get("ComSpeMoId") != null) {
            //zc修改
            //数量
            Integer ComNumber = MapUtils.getInteger(conInfo,"ComNumber");
            //实际数量
            Integer RealComNumber = MapUtils.getInteger(conInfo,"RealComNumber");
            //需出库的数量
            Integer zcCount = Math.abs(ComNumber-RealComNumber);
             conInfo.put("zcCount",zcCount);

            //ActionType 操作类型 1出库 2 入库
            //如果为入库，那么已出库的数量就是0
            if(MapUtils.getInteger(conInfo,"ActionType")==2){
                conInfo.put("DoneCount",0);
            }
             //如果为出库。那么已出库的数量就不变

            System.out.println("更改的参数"+conInfo);

            //型号不为空的时候
            Map<String, Object> moInfo = stockManageMapper.getShopMoForInfos(MapUtils.getString(conInfo, "ComSpeMoId"));
            if (moInfo.isEmpty()) {
                return JsonResult.error("获取商品信息失败");
            }
            List<MoSupplierObject> supplierObjectList = MoSupplierObjectUtil.convertJsonToList(MapUtils.getString(moInfo, "supplier"));
            MoSupplierObject supObj = MoSupplierObjectUtil.selectSupplierById(supplierObjectList, MapUtils.getString(conInfo, "SupId"));
            if (supObj == null) {
                return JsonResult.error("没有找到这个供应商绑定这个商品");
            }
            Map<String, Object> supplierOne = supplierManageMapper.getSupplierOne(supObj.getSupplierId());
            conInfo.put("supName", supplierOne.get("UnitName"));
            conInfo.put("signPrice", supObj.getPrice());
            conInfo.put("sumPrice", supObj.getPrice().multiply(new BigDecimal(MapUtils.getString(conInfo, "ComNumber"))));
            conInfo.put("shopInfo", moInfo);
            conInfo.put("ComType", ShopTypeSelectUtil.selectShopTypeById(MapUtils.getString(moInfo, "ComType")));
            conInfo.put("ComBrand", moInfo.get("ComBrand"));
        }
        System.out.println("最终的参数"+conInfo);
        return JsonResult.success(conInfo);
    }

}
